//
// Created by Administrator on 2021/9/28.
//

#ifndef MRENDER_LOG_H
#define MRENDER_LOG_H

#define MSG_LENGTH	2048 //最大消息长度
#define GET_FILE_NAME(fp) String::getFileName(fp);

#include <ctime>
#include <cstdarg>
#include "String.h"

/**
 * debug输出宏
 */
#define log_debug(frm, argc...) { \
    String s;                     \
    s += GET_FILE_NAME(__FILE__);                \
    s += " - [";                  \
    s += __func__;                \
    s +=  ",";                    \
    s += String::toString(__LINE__); \
    s += "] " ;                          \
    s += frm;                      \
    Log::printlog(LogLevel::DEBUG, s.c_str(), ##argc); \
};

/**
 * info输出宏
 */
#define log_info(frm, argc...) { \
    String s;                     \
    s += GET_FILE_NAME(__FILE__);                \
    s += " - [";                  \
    s += __func__;                \
    s +=  ",";                    \
    s += String::toString(__LINE__); \
    s += "] ";                           \
    s += frm;                         \
    Log::printlog(LogLevel::INFO, s.c_str(), ##argc);   \
};

/**
 * warn输出宏
 */
#define log_warn(frm, argc...) { \
    String s;                     \
    s += GET_FILE_NAME(__FILE__);                \
    s += " - [";                  \
    s += __func__;                \
    s +=  ",";                    \
    s += String::toString(__LINE__); \
    s += "] ";                           \
    s += frm;                         \
    Log::printlog(LogLevel::WARN, s.c_str(), ##argc);   \
};

/**
 * error输出宏
 */
#define log_error(frm, argc...) { \
    String s;                     \
    s += GET_FILE_NAME(__FILE__);                \
    s += " - [";                  \
    s += __func__;                \
    s +=  ",";                    \
    s += String::toString(__LINE__); \
    s += "] ";                           \
    s += frm;                          \
    Log::printlog(LogLevel::ERR, s.c_str(), ##argc);   \
};

/**
 * 日志级别
 */
enum LogLevel {
    DEBUG,INFO,WARN,ERR
};

/**
 * 日志
 */
class Log {
public:
    /**
     * 输出日志
     * @param LEVEL 级别
     * @param fmt 日志
     * @param ...
     */
    static void printlog(LogLevel level, const char* fmt, ...) {
        const char* LEVEL = "INFO";
        switch (level) {
            case LogLevel::DEBUG:
                LEVEL = "DEBUG";
                break;
            case LogLevel::INFO:
                LEVEL = "INFO";
                break;
            case LogLevel::WARN:
                LEVEL = "WARN";
                break;
            case LogLevel::ERR:
                LEVEL = "ERROR";
                break;
        }

        char msg[MSG_LENGTH];
        va_list arg;
        va_start(arg, fmt);
        _vsnprintf(msg, MSG_LENGTH, fmt, arg);
        va_end(arg);

        static struct tm tt;

        _getsystime(&tt);
        printf("%d-%d-%d %d:%0.2d:%0.2d [%s] %s\n", 1900 + tt.tm_year, 1 + tt.tm_mon,tt.tm_mday,tt.tm_hour,tt.tm_min, tt.tm_sec, LEVEL, msg);

        fflush(stdout);
    }
};
#endif //MRENDER_LOG_H
